package config

import (
	"go.uber.org/zap/zapcore"
	"strings"
)

type JWTConfig struct {
	SigningKey string `mapstructure:"key" json:"key"`
}

type ServerConfig struct {
	Name    string    `mapstructure:"name" json:"name"`
	Host    string    `mapstructure:"host" json:"host"`
	Port    int       `mapstructure:"port" json:"port"`
	JWTInfo JWTConfig `mapstructure:"jwt" json:"jwt"`
	DbType  []string  `mapstructure:"db_type" json:"db_type" yaml:"db_type"`
	MySQL   MySQL     `mapstructure:"mysql" json:"mysql" yaml:"mysql"`
	Redis   Redis     `mapstructure:"redis" json:"redis" yaml:"redis"`
	Mongo   Mongo     `mapstructure:"mongo" json:"mongo" yaml:"mongo"`
	Timer   Timer     `mapstructure:"timer" json:"timer" yaml:"timer"`
	Umeng   Umeng     `mapstructure:"umeng" json:"umeng" yaml:"umeng"`
	Zap     Zap       `mapstructure:"zap" json:"zap" yaml:"zap"`
}

type Umeng struct {
	Host           string `mapstructure:"host" json:"host" yaml:"host"`
	AndroidKey     string `mapstructure:"android_key" json:"android_key" yaml:"android_key"`
	AndroidSecrept string `mapstructure:"android_secrept" json:"android_secrept" yaml:"android_secrept"`
	IosKey         string `mapstructure:"ios_key" json:"ios_key" yaml:"ios_key"`
	IosSecrept     string `mapstructure:"ios_secrept" json:"ios_secrept" yaml:"ios_secrept"`
	DbName         string `mapstructure:"db_name" json:"db_name" yaml:"db_name"`
}

// mysql配置
type MySQL struct {
	User     string `mapstructure:"user" json:"user" yaml:"user"`
	Password string `mapstructure:"password" json:"password" yaml:"password"`
	Host     string `mapstructure:"host" json:"host" yaml:"host"`
	Port     string `mapstructure:"port" json:"port" yaml:"port"`
	DbName   string `mapstructure:"db_name" json:"db_name" yaml:"db_name"`
}

type OssConfig struct {
	Endpoint    string `mapstructure:"endpoint" json:"endpoint"`
	ApiKey      string `mapstructure:"key" json:"key"`
	ApiSecrect  string `mapstructure:"secrect" json:"secrect"`
	Host        string `mapstructure:"host" json:"host"`
	CallBackUrl string `mapstructure:"callback_url" json:"callback_url"`
	UploadDir   string `mapstructure:"upload_dir" json:"upload_dir"`
	BucketName  string `mapstructure:"bucket_name" json:"bucket_name"`
}

type Thrift struct {
	Port          string `mapstructure:"port" json:"port" yaml:"port"`
	TimeOutConn   int    `mapstructure:"time_out_conn" json:"time_out_conn" yaml:"time_out_conn"`
	TimeOutSocket int    `mapstructure:"time_out_socket" json:"time_out_socket" yaml:"time_out_socket"`
}

// redis 配置
type Redis struct {
	Host     string `mapstructure:"host" json:"host" yaml:"host"`
	Port     string `mapstructure:"port" json:"port" yaml:"port"`
	PassWord string `mapstructure:"pass_word" json:"pass_word" yaml:"pass_word"`
	IndexDB  int    `mapstructure:"index_db" json:"index_db" yaml:"index_db"`
}

// 切片服务配置
type Mongo struct {
	Username   string `mapstructure:"username" json:"username" yaml:"username"`
	Password   string `mapstructure:"password" json:"password" yaml:"password"`
	Url        string `mapstructure:"url" json:"url" yaml:"url"`
	Port       string `mapstructure:"port" json:"port" yaml:"port"`
	Database   string `mapstructure:"database" json:"database" yaml:"database"`
	RegisterDB bool   `mapstructure:"register_db" json:"register_db" yaml:"register_db"`
}

// 定时任务配置
type Timer struct {
	IsEnable    bool     `mapstructure:"is_enable" json:"is_enable" yaml:"is_enable"`          // 是否启用
	WithSeconds bool     `mapstructure:"with_seconds" json:"with_seconds" yaml:"with_seconds"` // 是否精确到秒
	Detail      []Detail `mapstructure:"detail" json:"detail" yaml:"detail"`
}

type Detail struct {
	IsEnable bool   `mapstructure:"is_enable" json:"is_enable" yaml:"is_enable"` // 是否启用
	TaskName string `mapstructure:"task_name" json:"task_name" yaml:"task_name"` // 任务名称
	Spec     string `mapstructure:"spec" json:"spec" yaml:"spec"`                // CRON表达式
}

// nacos 配置中心
type NacosConfig struct {
	Host        string `mapstructure:"host" json:"host"`
	Port        uint64 `mapstructure:"port" json:"port"`
	NamespaceId string `mapstructure:"namespace_id" json:"namespace_id"`
	DataId      string `mapstructure:"data_id" json:"data_id"`
	Group       string `mapstructure:"group" json:"group"`
}

type Zap struct {
	Level         string `mapstructure:"level" json:"level" yaml:"level"`                            // 级别
	Prefix        string `mapstructure:"prefix" json:"prefix" yaml:"prefix"`                         // 日志前缀
	Format        string `mapstructure:"format" json:"format" yaml:"format"`                         // 输出
	Director      string `mapstructure:"director" json:"director"  yaml:"director"`                  // 日志文件夹
	EncodeLevel   string `mapstructure:"encode-level" json:"encode-level" yaml:"encode-level"`       // 编码级
	StacktraceKey string `mapstructure:"stacktrace-key" json:"stacktrace-key" yaml:"stacktrace-key"` // 栈名

	MaxAge       int  `mapstructure:"max-age" json:"max-age" yaml:"max-age"`                      // 日志留存时间
	ShowLine     bool `mapstructure:"show-line" json:"show-line" yaml:"show-line"`                // 显示行
	LogInConsole bool `mapstructure:"log-in-console" json:"log-in-console" yaml:"log-in-console"` // 输出控制台
}

// ZapEncodeLevel 根据 EncodeLevel 返回 zapcore.LevelEncoder
// Author [SliverHorn](https://github.com/SliverHorn)
func (z *Zap) ZapEncodeLevel() zapcore.LevelEncoder {
	switch {
	case z.EncodeLevel == "LowercaseLevelEncoder": // 小写编码器(默认)
		return zapcore.LowercaseLevelEncoder
	case z.EncodeLevel == "LowercaseColorLevelEncoder": // 小写编码器带颜色
		return zapcore.LowercaseColorLevelEncoder
	case z.EncodeLevel == "CapitalLevelEncoder": // 大写编码器
		return zapcore.CapitalLevelEncoder
	case z.EncodeLevel == "CapitalColorLevelEncoder": // 大写编码器带颜色
		return zapcore.CapitalColorLevelEncoder
	default:
		return zapcore.LowercaseLevelEncoder
	}
}

// TransportLevel 根据字符串转化为 zapcore.Level
// Author [SliverHorn](https://github.com/SliverHorn)
func (z *Zap) TransportLevel() zapcore.Level {
	z.Level = strings.ToLower(z.Level)
	switch z.Level {
	case "debug":
		return zapcore.DebugLevel
	case "info":
		return zapcore.InfoLevel
	case "warn":
		return zapcore.WarnLevel
	case "error":
		return zapcore.WarnLevel
	case "dpanic":
		return zapcore.DPanicLevel
	case "panic":
		return zapcore.PanicLevel
	case "fatal":
		return zapcore.FatalLevel
	default:
		return zapcore.DebugLevel
	}
}
